package com.antoco.operation.bigscreen.controller.modelcontroller.impl;

import com.antoco.operation.bigscreen.controller.modelcontroller.intf.SensorReportController;
import com.antoco.operation.bigscreen.mapper.SensorReportMapper;
import com.antoco.operation.bigscreen.model.dto.SensorReportDTO;
import com.antoco.operation.bigscreen.model.entity.Sensor;
import com.antoco.operation.bigscreen.model.entity.SensorReport;
import com.antoco.operation.bigscreen.model.entity.SensorWarn;
import com.antoco.operation.bigscreen.service.WebSocketServer;
import com.antoco.operation.bigscreen.service.autogeneration.impl.SensorReportServiceImpl;
import com.antoco.operation.bigscreen.service.autogeneration.intf.SensorReportService;
import com.antoco.operation.bigscreen.service.autogeneration.intf.SensorService;
import com.antoco.operation.bigscreen.service.autogeneration.intf.SensorWarnService;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.List;
import java.util.stream.Collectors;

@RequestMapping("/model/sensor-report")
@RestController
public class SensorReportControllerImpl implements SensorReportController {

    @Autowired
    private SensorReportService sensorReportService;

    @Autowired
    private SensorReportMapper sensorReportMapper;

    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private SensorReportServiceImpl sensorReportServiceImpl;

    @Autowired
    private SensorService sensorService;

    @Autowired
    private SensorWarnService sensorWarnService;

    @Override
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public SensorReportDTO save(@Validated @RequestBody SensorReportDTO sensorReportDTO) throws Exception {
        SensorReport sensorReport = sensorReportMapper.asEntity(sensorReportDTO);
        sensorReport.setGenTime(new Timestamp(System.currentTimeMillis()));

        int reportVal = Integer.valueOf(sensorReport.getReportVal());
        //更加sensorId查询出sensor对象
        Sensor sensor = sensorService.findById(sensorReport.getSensorId()).orElse(new Sensor());
        int alarmLimitVal = Integer.valueOf(sensor.getAlarmLimitVal());//预警阈值
        int warnLimitVal = Integer.valueOf(sensor.getWarnLimitVal());//告警阈值
        //通讯值和传感器表的预警阈值和告警阈值进行对比
        if (reportVal > alarmLimitVal) {
            if (reportVal < warnLimitVal) {
                //设置状态
                sensor.setState("alarm");
                saveSensorWarn(sensor, reportVal, "1");
            } else if (reportVal > warnLimitVal) {
                //设置状态
                sensor.setState("warn");
                saveSensorWarn(sensor, reportVal, "2");
            }
        }
        sensorReportService.save(sensorReport);
        JSONObject result = sensorReportServiceImpl.findLatest(sensorReport.getId(), sensorReport.getSensorId());
        webSocketServer.send2Channel("SENSOR_REPORT", result.toString());
        return sensorReportDTO;
    }

    /**
     * 更新传感器信息，并保存告警记录
     * @param sensor 传感器
     * @param reportVal 通讯值
     * @param warnType 警告类型：1-预警，2-告警
     */
    private void saveSensorWarn(Sensor sensor, int reportVal, String warnType) {
        //更新传感器表
        sensorService.update(sensor, sensor.getId());
        //并生成一条sensor_warn记录
        SensorWarn sensorWarn = new SensorWarn();
        sensorWarn.setSensor(sensor);
        sensorWarn.setGenTime(new Timestamp(System.currentTimeMillis()));
        sensorWarn.setWarnVal(String.valueOf(reportVal));
        sensorWarn.setRecState("");
        sensorWarn.setWarnType(warnType);
        sensorWarnService.save(sensorWarn);
    }

    @Override
    @GetMapping("/{id}")
    public SensorReportDTO findById(@PathVariable("id") Long id) {
        SensorReport sensorReport = sensorReportService.findById(id).orElse(null);
        return sensorReportMapper.asDTO(sensorReport);
    }


    @Override
    @DeleteMapping("/{id}")
    public void delete(@PathVariable("id") Long id){
        sensorReportService.deleteById(id);
    }

    @Override
    @GetMapping
    public List<SensorReportDTO> list() {
        return sensorReportMapper.asDTOList(sensorReportService.findAll());
    }

    @Override
    @GetMapping("/page-query")
    public Page<SensorReportDTO> pageQuery(Pageable pageable) {
        Page<SensorReport> sensorReportPage = sensorReportService.findAll(pageable);
        List<SensorReportDTO> dtoList = sensorReportPage
                .stream()
                .map(sensorReportMapper::asDTO).collect(Collectors.toList());
        return new PageImpl<>(dtoList, pageable, sensorReportPage.getTotalElements());
    }

    @Override
    @PutMapping("/{id}")
    public SensorReportDTO update(@RequestBody SensorReportDTO sensorReportDTO, @PathVariable("id") Long id) {
        SensorReport sensorReport = sensorReportMapper.asEntity(sensorReportDTO);
        return sensorReportMapper.asDTO(sensorReportService.update(sensorReport, id));
    }

    @Override
    @GetMapping("/getlist/{id}")
    public String findAllBy(@PathVariable("id") Long id) {
        return sensorReportServiceImpl.findAllBy(id).toString();
    }
}